package com.link.play.fit.ai.utils

import android.annotation.SuppressLint
import android.text.format.DateFormat
import com.link.play.fit.ai.ext.d
import com.link.play.fit.ai.kv.AuthCache.timeDay
import java.text.ParseException
import java.text.SimpleDateFormat
import java.time.Instant
import java.time.LocalDate
import java.time.LocalTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.TimeZone
import kotlin.random.Random


object DateEx {

    fun getDayOfWeek(timestamp: Long): String {
        val days =
            arrayOf("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
        val calendar = Calendar.getInstance().apply { timeInMillis = timestamp }
        return days[calendar.get(Calendar.DAY_OF_WEEK) - 1]
    }

    fun getYearFromTimestamp(timestamp: Long): Int {
        val calendar: Calendar = Calendar.getInstance()
        calendar.setTimeInMillis(timestamp)
        return calendar.get(Calendar.YEAR) // 返回年份
    }

    fun getMonthFromTimestamp(timestamp: Long): Int {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = timestamp
        return calendar[Calendar.MONTH] + 1 // 返回月份，需要加1因为Calendar.MONTH是从0开始的
    }

    fun getDayOfMonthFromTimestamp(timestamp: Long): Int {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = timestamp
        return calendar[Calendar.DAY_OF_MONTH] // 返回当前是月份的第几天
    }

    fun getDaySuffix(day: Int): String {
        return when (day) {
            1, 21, 31 -> "st"
            2, 22 -> "nd"
            3, 23 -> "rd"
            else -> "th"
        }
    }

    fun getHourOfDayFromTimestamp(timestamp: Long): Int {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = timestamp
        return calendar[Calendar.HOUR_OF_DAY] // 返回当前小时（24小时制）
    }

    fun getMinuteFromTimestamp(timestamp: Long): Int {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = timestamp
        return calendar[Calendar.MINUTE] // 返回当前分钟
    }

    // 获取时间 hh:mm a  12小时制
    fun getHourAndMinute(): String {
        val formatter = DateTimeFormatter.ofPattern("hh:mm a")
        return DateFormat.format("hh:mm a", Date()).toString()
    }


    /**
     * month是从1开的
     */
    fun getTimestampFromDateTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): Long {
        val calendar = Calendar.getInstance()
        calendar[year, month - 1, day, hour] = minute
        return calendar.timeInMillis // 返回对应的时间戳
    }


    fun daysInMonth(year: Int, month: Int): Int {
        // 每个月的天数，二月默认为28天
        val monthDays = arrayOf(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

        // 检查是否是闰年
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
            monthDays[1] = 29 // 如果是闰年，二月有29天
        }

        // 返回给定月份的天数
        return monthDays[month - 1]
    }

    @SuppressLint("SimpleDateFormat")
    fun generateRandomBirthdayTimestamp(age: Int): Long {
        val currentTimeMillis = System.currentTimeMillis()

        // 计算出生年份
        val birthYear = 2024 - age

        // 随机选择一个月份
        val randomMonth = Random.nextInt(12) + 1

        // 随机选择一个日期，确保是该月的有效日期
        val randomDay = Random.nextInt(28) + 1 // 简单起见，我们假设日期不会超过28

        // 构建出生日期字符串，包括时间部分
        val birthDate = "$birthYear-${randomMonth.toString().padStart(2, '0')}-${
            randomDay.toString().padStart(2, '0')
        } 00:00:00"

        // 将字符串转换为时间戳
        return try {
            // 尝试解析日期字符串
            val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
            dateFormat.parse(birthDate)?.time ?: currentTimeMillis
        } catch (e: ParseException) {
            // 如果解析失败，返回当前时间戳
            currentTimeMillis
        }
    }

    fun calculateAge(birthTimestamp: Long): Int {
        // 创建一个 Calendar 实例
        val birthCalendar = Calendar.getInstance()
        // 设置时间戳对应的日期
        birthCalendar.timeInMillis = birthTimestamp

        // 创建一个 Calendar 实例用于获取当前日期
        val currentCalendar = Calendar.getInstance()

        // 计算年龄
        var age = currentCalendar.get(Calendar.YEAR) - birthCalendar.get(Calendar.YEAR)

        // 如果当前日期还没有到生日，则年龄减一
        if (currentCalendar.get(Calendar.DAY_OF_YEAR) < birthCalendar.get(Calendar.DAY_OF_YEAR)) {
            age--
        }

        return age
    }


//    fun formatTimeAgo(timestamp: Long): String {
//        val instant = Instant.ofEpochMilli(timestamp)
//        val now = LocalDateTime.now(ZoneId.systemDefault())
//        val then = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
//
//        val seconds = ChronoUnit.SECONDS.between(then, now)
//        val minutes = ChronoUnit.MINUTES.between(then, now)
//        val hours = ChronoUnit.HOURS.between(then, now)
//        val days = ChronoUnit.DAYS.between(then, now)
//
//        return when {
//            days > 0 -> days.toString() + "day ago"
//            hours > 0 -> hours.toString() + "H ago"
//            minutes > 0 -> minutes.toString() + "Min ago"
//            else -> seconds.toString() + "s ago"
//        }
//    }

    fun formatTimeAgo(timestamp: Long): String {
        val then = Date(timestamp)
        val now = Date()
        val diff = now.time - then.time

        if (diff < 1000 * 60) {
            // less than a minute
            return (diff / 1000).toString() + "s ago"
        } else if (diff < 1000 * 60 * 60) {
            // less than an hour
            return (diff / (1000 * 60)).toString() + "Min ago"
        } else if (diff < 1000 * 60 * 60 * 24) {
            // less than a day
            return (diff / (1000 * 60 * 60)).toString() + "H ago"
        } else {
            // more than a day
            return (diff / (1000 * 60 * 60 * 24)).toString() + "day ago"
        }
    }

    fun getDayOfMonth(): String {
        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
        val formattedDate = LocalDate.now().format(formatter)
        return timeDay.ifEmpty {
            formattedDate
        }
    }

    fun getyyMMdd(t:Long):String{
        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
        val zonedDateTime = Instant.ofEpochMilli(t)
            .atZone(ZoneId.systemDefault())
        val formattedDate = zonedDateTime.format(formatter)
        return formattedDate
    }

    fun getCurrentDayOfMonth(): String {
        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
        val formattedDate = LocalDate.now().format(formatter)
        return formattedDate
    }

    fun getDayOfMonthByLocal(localeDate: LocalDate): String {
        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")

        val formattedDate = localeDate.format(formatter)
        return formattedDate
    }

    fun getTimeStamp(dateString: String): String {
        val localDate = LocalDate.parse(dateString)
        val timestampMillis = localDate
            .atStartOfDay(ZoneId.of("UTC"))
            .toInstant()
            .toEpochMilli()
        return timestampMillis.toString()
    }

    fun getPmDate(timestampMillis: String): String {

        if (timestampMillis.isEmpty()) return ""
        val zonedDateTime = Instant.ofEpochMilli(timestampMillis.toLong())
            .atZone(ZoneId.systemDefault()) // 系统默认时区

        val formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH)

        val formattedTime = zonedDateTime.format(formatter)

        return formattedTime
    }

    fun getTimestampForDaysAgo(daysAgo: Int): Long {
        val date = LocalDate.now().minusDays(daysAgo.toLong())
        val startOfDay = date.atStartOfDay()
        return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
    }

    fun getTimestampForMonthsAgo(monthsAgo: Int): Long {
        val date = LocalDate.now().minusMonths(monthsAgo.toLong())
        val firstDayOfMonth = date.withDayOfMonth(1)
        val startOfDay = firstDayOfMonth.atStartOfDay()
        return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
    }

    fun getTimestampForYearsAgo(yearsAgo: Int): Long {
        val date = LocalDate.now().minusYears(yearsAgo.toLong())
        val firstDayOfYear = date.withDayOfYear(1)
        val startOfDay = firstDayOfYear.atStartOfDay()
        return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
    }


    fun parseTime(timeStr: String): Calendar {
        val sdf = SimpleDateFormat("hh:mm:a", Locale.US)
        val date = sdf.parse(timeStr)
//        Calendar.getInstance().apply { time = date }

//        val date = sdf.parse(timeStr.replace(":", "")) // 处理格式 "09:22:AM" -> "09:22AM"
        return Calendar.getInstance().apply { time = date }
    }

    // 获取当前时间并格式化为 AM/PM 格式
    fun getCurrentTimeAmPm(): String {
        val sdf = SimpleDateFormat("hh:mm a", Locale.US) // 格式如 "03:45 PM"
        return sdf.format(Date()) // Date() 默认使用系统时区
    }

    fun parseTimeToUs(timeStr: String): Calendar {

        val sdf = SimpleDateFormat("hh:mm:a",  Locale.US)
        val date = sdf.parse(timeStr) ?: throw IllegalArgumentException("Invalid time format")

        val calendar = Calendar.getInstance().apply {
            time = date
            // 固定秒和毫秒为0
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }
        return calendar
    }

    fun convertToTimestamp(timeStr: String): Long {
        return try {
            // 预处理字符串
            val formattedStr = timeStr.replace(":PM", " PM").replace(":AM", " AM")

            // 定义解析格式
            val sdf = SimpleDateFormat("hh:mm a", Locale.US)

            // 解析为Date对象
            val date = sdf.parse(formattedStr)

            // 转换为时间戳（毫秒）
            date?.time ?: throw IllegalArgumentException("Invalid time format")
        } catch (e: Exception) {
            -1 // 返回-1表示失败，可根据需求调整
        }
    }

    fun isCurrentTimeAfter(targetTime:String): Boolean {
        // 目标时间字符串预处理（适配"06:01:PM"格式）
        val targetTimeStr =  targetTime
            .replace(":PM", " PM")
            .replace(":AM", " AM")

        return try {
            // 1. 创建日期格式化工具
            val sdf = SimpleDateFormat("hh:mm a", Locale.US).apply {
                timeZone = TimeZone.getDefault() // 使用系统时区
            }

            // 2. 解析目标时间（自动关联当前日期）
            val targetDate = sdf.parse(targetTimeStr)

            // 3. 获取当前时间
            val currentDate = Calendar.getInstance().time
            // 4. 比较时间戳
            currentDate.after(targetDate)
        } catch (e: Exception) {
            e.printStackTrace()
            false // 解析失败时默认返回 false
        }
    }

    fun isAfterTargetTime(targetTime: String): Boolean {
        val targetTimeStr =  targetTime
            .replace(":PM", " PM")
            .replace(":AM", " AM")

        // 定义时间格式
        val formatter = DateTimeFormatter.ofPattern("hh:mm a",  Locale.US)

        // 解析目标时间
        val target = LocalTime.parse(targetTimeStr, formatter)

        // 获取当前时间
        val now = LocalTime.now()

        // 直接比较
        return now.isAfter(target)
    }

    fun convertToDailyTimestamp(timeStr: String): Long {
        return try {
            // 1. 预处理输入字符串
            val formattedTime = timeStr
                .replace(":PM", " PM")
                .replace(":AM", " AM")

            // 2. 创建日期格式化工具
            val sdf = SimpleDateFormat("hh:mm a", Locale.US).apply {
                timeZone = TimeZone.getDefault() // 使用系统时区
            }

            // 3. 解析时间（得到的时间会是 1970-01-01 的对应时间）
            val parsedDate = sdf.parse(formattedTime) ?: return -1

            // 4. 结合当前日期生成正确的时间
            val calendar = Calendar.getInstance().apply {
                // 获取当前年月日
                val now = Calendar.getInstance()
                set(Calendar.YEAR, now.get(Calendar.YEAR))
                set(Calendar.MONTH, now.get(Calendar.MONTH))
                set(Calendar.DAY_OF_MONTH, now.get(Calendar.DAY_OF_MONTH))

                // 设置解析出的小时和分钟
                val parsedCalendar = Calendar.getInstance().apply { time = parsedDate }
                set(Calendar.HOUR_OF_DAY, parsedCalendar.get(Calendar.HOUR_OF_DAY))
                set(Calendar.MINUTE, parsedCalendar.get(Calendar.MINUTE))
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }

            calendar.timeInMillis
        } catch (e: Exception) {
            -1
        }
    }

}